package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.heima.common.exception.CustomException;
import com.heima.feign.article.IArticleClient;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.pojos.WmChannel;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.wemedia.mapper.WmChannelMapper;
import com.heima.wemedia.mapper.WmNewsMapper;
import com.heima.wemedia.mapper.WmUserMapper;
import com.heima.wemedia.service.BaiduScanService;
import com.heima.wemedia.service.WmAutoScanService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

/**
 * @author jack
 * @data 2024 11:31
 */
@Service
@Transactional
@Slf4j
public class WmAutoScanServiceImpl implements WmAutoScanService {
    @Autowired
    private WmNewsMapper wmNewsMapper;
    @Autowired
    private BaiduScanService baiduScanService;
    @Autowired
    private IArticleClient iArticleClient;
    @Autowired
    private WmUserMapper wmUserMapper;
    @Autowired
    private WmChannelMapper wmChannelMapper;
    /**
     * 文章自动审核功能
     *
     * @param newsId
     */
    @Override
    public void autoScan(Integer newsId) {
        //1. 根据文章id校验文章信息：a. 文章是否存在; b.文章是否处于待审核状态
        WmNews wmNews = wmNewsMapper.selectById(newsId);
        if (wmNews == null || wmNews.getStatus() != WmNews.Status.SUBMIT.getCode()){
            throw new CustomException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }

        //2. 提取文章中所有的文本和图片
        Map<String,Object> textAndImg = handleTextAndImg(wmNews);

        //3. 先审核文本
        boolean isTextScan = scanText((String) textAndImg.get("text"),wmNews);
        if (!isTextScan) return;

        //4. 再审核图片
        boolean isImgScan = scanImg((HashSet<String>) textAndImg.get("img"),wmNews);
        if (!isImgScan) return;

        //5. 远程调用article微服务，将自媒体文章信息wm_news同步到ap_article,ap_article_config,ap_article_content
        saveArticle(wmNews);
    }

    //远程调用article微服务，实现自媒体文章同步到app端
    private void saveArticle(WmNews wmNews) {
        ArticleDto articleDto = new ArticleDto();
        BeanUtils.copyProperties(wmNews,articleDto);

        //以下字段需要单独处理
        //app文章id: articleId
        Long aid = wmNews.getArticleId();
        if (aid != null){
            //说明当前文章之前同步过，本次操作属于修改
            articleDto.setId(aid);
        }

        //作者id
        articleDto.setAuthorId(wmNews.getUserId().longValue());
        //作者名字
        WmUser wmUser = wmUserMapper.selectById(wmNews.getUserId());
        if (wmUser != null){
            articleDto.setAuthorName(wmUser.getName());
        }
        //频道名字
        WmChannel wmChannel = wmChannelMapper.selectById(wmNews.getChannelId());
        if (wmChannel != null){
            articleDto.setChannelName(wmChannel.getName());
        }

        //文章布局
        articleDto.setLayout(wmNews.getType());

        //调用feign接口，将数据传递给article微服务进行保存
        ResponseResult result = iArticleClient.saveArticle(articleDto);

        if (result.getCode() == 200){
            //同步app文章数据成功，切记要回填：article_id字段到wm_news表中
            String articleId = result.getData().toString();
            wmNews.setArticleId(Long.valueOf(articleId));
            updateNewsStatus(wmNews,WmNews.Status.PUBLISHED,"审核成功");
        }


    }

    //审核文章的图片内容
    private boolean scanImg(HashSet<String> imgs, WmNews wmNews) {
        //调用百度云接口审核
        for (String img : imgs) {
            Map<String, Object> map = baiduScanService.scanImg(img);
            int conclusionType = Integer.valueOf(map.get("conclusionType").toString());
            if (conclusionType == 2 || conclusionType == 4){
                //不合规：修改文章状态：2 审核失败
                updateNewsStatus(wmNews, WmNews.Status.FAIL, "审核失败：图片内容违规!");
                return false;
            }else if (conclusionType == 3){
                //疑似违规：修改文章状态：3 待人工审核
                updateNewsStatus(wmNews, WmNews.Status.ADMIN_AUTH, "待人工审核：图片内容疑似违规!");
                return false;
            }
        }

        return true;
    }



    //审核文章的文本内容
    private boolean scanText(String text, WmNews wmNews) {
        //todo: 先内审
        //再外审 -- 调用百度云接口审核
        Map<String, Object> resMap = baiduScanService.scanText(text);
        int conclusionType = Integer.valueOf(resMap.get("conclusionType").toString());
        if (conclusionType == 2 || conclusionType == 4){
            //不合规：修改文章状态：2 审核失败
            updateNewsStatus(wmNews, WmNews.Status.FAIL, "审核失败：文本内容违规!");
            return false;
        }else if (conclusionType == 3){
            //疑似违规：修改文章状态：3 待人工审核
            updateNewsStatus(wmNews, WmNews.Status.ADMIN_AUTH, "待人工审核：文本内容疑似违规!");
            return false;
        }

        return true;
    }

    //提取文章中所有的文本和图片
    private Map<String, Object> handleTextAndImg(WmNews wmNews) {
        //用来收集文章中的所有文本内容
        StringBuilder textContainer = new StringBuilder(wmNews.getTitle());
        //用来收集文章中的所有图片内容
        HashSet<String> imgContainer = new HashSet<>();

        //处理文章内容部分
        String contentStr = wmNews.getContent();
        JSONArray jsonArray = JSON.parseArray(contentStr);
        for (Object obj : jsonArray) {
            JSONObject jsonObject = JSONObject.parseObject(obj.toString());
            if ("text".equals(jsonObject.getString("type"))){
                textContainer.append(jsonObject.getString("value"));
            }else {
                imgContainer.add(jsonObject.getString("value"));
            }
        }

        //处理文章标签
        textContainer.append(wmNews.getLabels());

        Map<String, Object> res = new HashMap<>();
        res.put("text",textContainer.toString());
        res.put("img",imgContainer);

        return res;
    }

    //修改文章状态
    private void updateNewsStatus(WmNews wmNews, WmNews.Status fail, String reason) {
        wmNews.setStatus(fail.getCode());
        wmNews.setReason(reason);
        wmNewsMapper.updateById(wmNews);
    }
}
